﻿using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

using NinjaToolbox.PhysicsSystem;

[CustomEditor(typeof(PhysicsObject))]
public class PhysicsObjectInspector : Editor
{
    bool mIsEnabledDebugSettings;

    OBBBoxSceneGUIDrawer mObbBoxSceneGUIDrawer;
    OBBBoxSceneGUIDrawer ObbBoxSceneGUIDrawer
    {
        get
        {
            if (mObbBoxSceneGUIDrawer == null)
            {
                mObbBoxSceneGUIDrawer = new OBBBoxSceneGUIDrawer();
                var colliderObject = target as PhysicsObject;
                mObbBoxSceneGUIDrawer.Initialization(() => colliderObject.ColliderShape);

                mObbBoxSceneGUIDrawer.OnObbBoxChanged += (obb) =>
                {
                    (target as PhysicsObject).SetColliderShape(obb);
                };
            }

            return mObbBoxSceneGUIDrawer;
        }
    }

    bool mShapeIsUnfold;
    bool mErrorSettingsIsUnfold;
    bool mGroundSettingsIsUnfold;
    bool mGravitySettingsIsUnfold;
    bool mFallingHeadFixSettingsIsUnfold;


    void Awake()
    {
        ObbBoxSceneGUIDrawer.GetHashCode();
    }

    void OnDestroy()
    {
        ObbBoxSceneGUIDrawer.Dispose();
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        var shapeOffsetProp = serializedObject.FindProperty("mColliderShape.offset");
        var shapeSizeProp = serializedObject.FindProperty("mColliderShape.size");
        var virtualRayLengthProp = serializedObject.FindProperty("errorSettings.virtualRayLength");
        var movingErrorProp = serializedObject.FindProperty("errorSettings.movingError");
        var movingDetectTimeSpacingProp = serializedObject.FindProperty("errorSettings.movingDetectTimeSpacing");
        var fallingHeadFixErrorProp = serializedObject.FindProperty("errorSettings.fallingHeadFixError");

        var groundSettings_EnableProp = serializedObject.FindProperty("groundSettings.enabled");
        var groundSettings_useFootPointProp = serializedObject.FindProperty("groundSettings.useFootPoint");
        var groundSettings_footPointProp = serializedObject.FindProperty("groundSettings.footPoint");
        var groundSettings_footPointRelativeOffsetProp = serializedObject.FindProperty("groundSettings.footPointRelativeOffset");
        var groundSettings_groundLayerProp = serializedObject.FindProperty("groundSettings.groundLayer");
        var groundSettings_groundDetectLineLengthProp = serializedObject.FindProperty("groundSettings.groundDetectLineLength");

        var gravitySettings_EnableProp = serializedObject.FindProperty("gravitySettings.enabled");
        var gravitySettings_PresetProp = serializedObject.FindProperty("gravitySettings.preset");
        var gravitySettings_GravityAcceProp = serializedObject.FindProperty("gravitySettings.gravityAcce");
        var gravitySettings_GravityAcceScaleProp = serializedObject.FindProperty("gravitySettings.gravityAcceScale");
        var gravitySettings_GravityAcceLimitProp = serializedObject.FindProperty("gravitySettings.gravityAcceLimit");
        var gravitySettings_GravityScaleProp = serializedObject.FindProperty("gravitySettings.gravityScale");

        var fallingHeadFixSettings_EnableProp = serializedObject.FindProperty("fallingHeadFixSettings.enabled");
        var fallingHeadFixSettings_FixCenterOffsetPointProp = serializedObject.FindProperty("fallingHeadFixSettings.fixCenterOffsetPoint");
        var fallingHeadFixSettings_GradientProp = serializedObject.FindProperty("fallingHeadFixSettings.gradient");
        var fallingHeadFixSettings_RadiusProp = serializedObject.FindProperty("fallingHeadFixSettings.radius");
        var fallingHeadFixSettings_MinSpeedProp = serializedObject.FindProperty("fallingHeadFixSettings.minSpeed");
        var fallingHeadFixSettings_MaxSpeedProp = serializedObject.FindProperty("fallingHeadFixSettings.maxSpeed");
        var fallingHeadFixSettings_SpeedAreaTopExternProp = serializedObject.FindProperty("fallingHeadFixSettings.speedAreaTopExtern");
        var fallingHeadFixSettings_speedAreaBottomExternProp = serializedObject.FindProperty("fallingHeadFixSettings.speedAreaBottomExtern");

        var isDrawGizmosProp = serializedObject.FindProperty("isDrawGizmos");
        var alwaysVisibleGizmosProp = serializedObject.FindProperty("alwaysVisibleGizmos");

        using (var changeCheck = new EditorGUI.ChangeCheckScope())
        {
            mShapeIsUnfold = EditorGUILayout.Foldout(mShapeIsUnfold, "Shape");
            if (mShapeIsUnfold)
            {
                EditorGUI.indentLevel++;
                ObbBoxSceneGUIDrawer.DrawInspectorGUI();
                EditorGUILayout.PropertyField(shapeOffsetProp);
                EditorGUILayout.PropertyField(shapeSizeProp);
                EditorGUI.indentLevel--;
            }

            mErrorSettingsIsUnfold = EditorGUILayout.Foldout(mErrorSettingsIsUnfold, "ErrorSettings");
            if (mErrorSettingsIsUnfold)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.PropertyField(virtualRayLengthProp);
                EditorGUILayout.PropertyField(movingErrorProp);
                EditorGUILayout.PropertyField(movingDetectTimeSpacingProp);
                EditorGUILayout.PropertyField(fallingHeadFixErrorProp);
                EditorGUI.indentLevel--;
            }

            mGroundSettingsIsUnfold = EditorGUILayout.Foldout(mGroundSettingsIsUnfold, "GroundSettings");
            if (mGroundSettingsIsUnfold)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.PropertyField(groundSettings_EnableProp);

                using (new EditorGUI.DisabledGroupScope(!groundSettings_EnableProp.boolValue))
                {
                    EditorGUILayout.PropertyField(groundSettings_useFootPointProp);

                    using (new EditorGUI.DisabledGroupScope(!groundSettings_useFootPointProp.boolValue))
                    {
                        EditorGUILayout.PropertyField(groundSettings_footPointProp);
                    }

                    using (new EditorGUI.DisabledGroupScope(groundSettings_useFootPointProp.boolValue))
                    {
                        EditorGUILayout.PropertyField(groundSettings_footPointRelativeOffsetProp);
                    }

                    EditorGUILayout.PropertyField(groundSettings_groundLayerProp);
                    EditorGUILayout.PropertyField(groundSettings_groundDetectLineLengthProp);
                }
                EditorGUI.indentLevel--;
            }

            mGravitySettingsIsUnfold = EditorGUILayout.Foldout(mGravitySettingsIsUnfold, "GravitySettings");
            if (mGravitySettingsIsUnfold)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.PropertyField(gravitySettings_EnableProp);

                using (new EditorGUI.DisabledGroupScope(!gravitySettings_EnableProp.boolValue))
                {
                    EditorGUILayout.PropertyField(gravitySettings_PresetProp);

                    using (new EditorGUI.DisabledGroupScope(gravitySettings_PresetProp.objectReferenceValue != null))
                    {
                        EditorGUILayout.PropertyField(gravitySettings_GravityAcceProp);
                        EditorGUILayout.PropertyField(gravitySettings_GravityAcceScaleProp);
                        EditorGUILayout.PropertyField(gravitySettings_GravityAcceLimitProp);
                        EditorGUILayout.PropertyField(gravitySettings_GravityScaleProp);
                    }
                }
                EditorGUI.indentLevel--;
            }

            mFallingHeadFixSettingsIsUnfold = EditorGUILayout.Foldout(mFallingHeadFixSettingsIsUnfold, "FallingHeadFixSettings");
            if (mFallingHeadFixSettingsIsUnfold)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.PropertyField(fallingHeadFixSettings_EnableProp);

                using (new EditorGUI.DisabledGroupScope(!fallingHeadFixSettings_EnableProp.boolValue))
                {
                    EditorGUILayout.PropertyField(fallingHeadFixSettings_FixCenterOffsetPointProp);
                    EditorGUILayout.PropertyField(fallingHeadFixSettings_GradientProp);
                    EditorGUILayout.PropertyField(fallingHeadFixSettings_RadiusProp);
                    EditorGUILayout.PropertyField(fallingHeadFixSettings_MinSpeedProp);
                    EditorGUILayout.PropertyField(fallingHeadFixSettings_MaxSpeedProp);
                    EditorGUILayout.PropertyField(fallingHeadFixSettings_SpeedAreaTopExternProp);
                    EditorGUILayout.PropertyField(fallingHeadFixSettings_speedAreaBottomExternProp);
                }
                EditorGUI.indentLevel--;
            }
            EditorGUILayout.PropertyField(isDrawGizmosProp);
            EditorGUILayout.PropertyField(alwaysVisibleGizmosProp);

            if (changeCheck.changed)
            {
                GUI.changed = true;
                serializedObject.ApplyModifiedProperties();
            }
        }
    }

    public override bool HasPreviewGUI()
    {
        return true;
    }

    public override GUIContent GetPreviewTitle()
    {
        return new GUIContent("Physics Object Debug Information");
    }

    public override void OnPreviewGUI(Rect r, GUIStyle background)
    {
        var concertPhysicsObject = base.target as PhysicsObject;

        var y = r.y;
        EditorGUI.LabelField(new Rect(r.x, y, r.width, 20), "IsOnGround: " + concertPhysicsObject.IsOnGround, EditorStyles.whiteLabel);
        y += 20;
        EditorGUI.LabelField(new Rect(r.x, y, r.width, 20), "IsMoving: " + concertPhysicsObject.IsMoving, EditorStyles.whiteLabel);
        y += 20;
        EditorGUI.LabelField(new Rect(r.x, y, r.width, 20), "IsRising: " + concertPhysicsObject.IsRising, EditorStyles.whiteLabel);
        y += 20;
        EditorGUI.LabelField(new Rect(r.x, y, r.width, 20), "IsFalling: " + concertPhysicsObject.IsFalling, EditorStyles.whiteLabel);
        y += 20;
        EditorGUI.LabelField(new Rect(r.x, y, r.width, 20), "Velocity: " + concertPhysicsObject.Velocity, EditorStyles.whiteLabel);
    }
}
